package local_server

// 导入必要的包
import (
	"Lunar-Astral-API/local_server/bundler"  // 分卷压缩包
	"Lunar-Astral-API/local_server/config"   // 项目配置相关包
	"Lunar-Astral-API/local_server/handlers" // 处理API请求的包
	"Lunar-Astral-API/local_server/llama"    // GGUF相关包
	"Lunar-Astral-API/local_server/release"  // 端口释放相关包
	"flag"                                   // 用于解析命令行参数
	"log"                                    // 用于日志记录
	"mime"                                   // 用于处理MIME类型
	"net/http"                               // 用于构建HTTP服务器
	"os"                                     // 用于操作系统相关操作
	"os/signal"                              // 用于处理系统信号
	"syscall"                                // 用于系统调用
)

// CreateSystemServer 函数是程序的入口点，负责初始化服务器并启动服务
func CreateSystemServer() {
	// 初始化服务器
	initializeServer()
	// 设置信号处理
	quit := setupSignalHandling()
	// 启动服务器
	server := startServer()
	// 等待关闭信号并优雅关闭
	waitForShutdown(quit, server)
}

// initializeServer 初始化服务器配置和组件
func initializeServer() {
	// 解析命令行参数
	flag.Parse()
	// 检查是否为控制面板模式
	if *config.ControlPanelMode {
		log.Printf("控制面板模式 -> 启动控制面板服务，端口: %d", *config.ControlPanelPort)
		setupControlPanelServer()
		return
	}
	// 如果指定了输出基础名和分卷大小，则执行分卷压缩
	if *config.OutBase != "" && *config.PartSizeMB != 0 {
		bundler.ExecutePackageProcess()
		return
	}
	// 如果指定了端口释放选项，则执行端口释放
	if *config.PortRelease {
		release.ExecutePortRelease()
		return
	}
	// 设置MIME类型
	setupMimeTypes()
	// 创建本地目录
	createLocalDirectory()
	// 注册HTTP处理器
	registerHandlers()
	// 初始化GGUF服务器（如果需要）
	initializeGGFUServers()
}

// setupMimeTypes 设置MIME类型映射
func setupMimeTypes() {
	for ext, mimeType := range config.MimeMap {
		mime.AddExtensionType(ext, mimeType)
	}
}

// createLocalDirectory 创建本地数据目录
func createLocalDirectory() {
	// 0755 表示目录的权限为所有者可读写执行，组和其他用户可读执行
	if err := os.MkdirAll(config.LocalDir, 0755); err != nil {
		log.Fatalf("LLMS服务[ERROR] -> %v", err)
	}
}

// registerHandlers 注册所有HTTP请求处理器
func registerHandlers() {
	// 处理根路径请求，将请求路径中的前缀 "/" 去除后，使用文件服务器提供 Webpage 目录下的静态文件
	http.Handle("/", http.StripPrefix("/", http.FileServer(http.Dir("webpage"))))
	// 注册所有API路径的处理函数
	apiHandlers := map[string]http.HandlerFunc{
		"/live2d/":   handlers.Live2dModelsHandler,
		"/save":      handlers.SaveHandler,
		"/read/":     handlers.ReadHandler,
		"/files/":    handlers.FileListHandler,
		"/download/": handlers.DownloadHandler,
		"/delete/":   handlers.DeleteHandler,
		"/archive":   handlers.ArchiveHandler,
		"/v1/models": handlers.AgentRuleModelsHandler,
		"/v1/":       handlers.AgentRuleHandler,
	}
	for path, handler := range apiHandlers {
		http.HandleFunc(path, handler)
	}
}

// initializeGGFUServers 初始化GGUF相关服务器
func initializeGGFUServers() {
	// 检查模型系统端口是否为 0。若为 0，则表示需要创建 GGUF 相关服务器
	if *config.ModelSystemPort == 0 {
		// 调用 gguf 包中的 CreateServers 函数创建服务器
		llama.CreateServers()
	}
}

// setupSignalHandling 设置系统信号处理
func setupSignalHandling() chan os.Signal {
	// 创建一个用于接收系统信号的通道，缓冲区大小为 1
	quit := make(chan os.Signal, 1)
	// 监听 SIGINT 和 SIGTERM 信号，当接收到这些信号时，将信号发送到 quit 通道
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	return quit
}
